package com.cskaoyan.thread02.model.edition2;

/*
         智能蒸笼:
        1. 线程间同步，因为eatFood方法运行在消费者线程，setFood运行在生产者线程
           所以对于生产者线程，消费者的线程同步，通过eatFood和setFood实现
           将他们变成同步方法(使用同一个锁对象，即同一个蒸笼对象)

       2. 线程间的协作，因为eatFood方法运行在消费者线程，setFood运行在生产者线程
          所以，我们只需要在eatFood方法和setFood方法体，实现阻止自己，通知别人
          实现线程间的协作了
 */
public class Container {

    private Food food;


    /*
         给生产者线程使用，放入包子的方法
         因为和eatFood方法在同一个蒸笼对象上被调用 this相同
     */
    public synchronized void setFood(Food newFood) {
        // 运行在生产者线程
        if (food != null) {
           // 蒸笼非空
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            // 蒸笼是空的
            System.out.println(Thread.currentThread().getName() + "做了：" + newFood);
            // 将包子放入蒸笼
            food = newFood;

            // 通知别人(消费者线程)
            this.notifyAll();
        }

    }


    /*
         给消费者线程使用，吃包子
         因为和setFood方法，同一个蒸笼对象上被调用 this相同
     */
    public synchronized void eatFood() {
        // 运行在消费者线程
        if (food == null) {
            // 蒸笼为空
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } else {
            // 蒸笼不空
            System.out.println(Thread.currentThread().getName() + "吃了: " + food);
            // 吃包子
            food = null;

            // 通知别人
            this.notifyAll();
        }


    }
}

/*
      该类表示蒸笼中的包子
 */
class Food {
    private String name;

    private double price;

    public Food(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Food{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}
